home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!wyse!mikew
- From: mikew@wyse.wyse.com (Mike Wexler)
- Newsgroups: comp.sources.x
- Subject: v03i019: Ardent Window Manager, Patchlevel 9, Part03/12
- Message-ID: <2069@wyse.wyse.com>
- Date: 17 Feb 89 19:16:37 GMT
- Organization: Wyse Technology, San Jose
- Lines: 1987
- Approved: mikew@wyse.com
-
- Submitted-by: kmw@ardent (Ken Wallich)
- Posting-number: Volume 3, Issue 19
- Archive-name: awm2/part03
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 3 (of 12)."
- # Contents: Resize.c menus/menu.c menus/menu.ext.h
- # Wrapped by mikew@wyse on Fri Feb 17 10:50:21 1989
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Resize.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Resize.c'\"
- else
- echo shar: Extracting \"'Resize.c'\" \(15574 characters\)
- sed "s/^X//" >'Resize.c' <<'END_OF_FILE'
- X
- X
- X
- X#ifndef lint
- Xstatic char *rcsid_Resize_c = "$Header: /usr/graph2/X11.3/contrib/windowmgrs/awm/RCS/Resize.c,v 1.2 89/02/07 21:23:37 jkh Exp $";
- X#endif lint
- X
- X#include "X11/copyright.h"
- X/*
- X *
- X * Copyright 1987, 1988 by Ardent Computer Corporation, Sunnyvale, Ca.
- X *
- X * Copyright 1987 by Jordan Hubbard.
- X *
- X *
- X * All Rights Reserved
- X *
- X * Permission to use, copy, modify, and distribute this software and its
- X * documentation for any purpose and without fee is hereby granted,
- X * provided that the above copyright notice appear in all copies and that
- X * both that copyright notice and this permission notice appear in
- X * supporting documentation, and that the name of Ardent Computer
- X * Corporation or Jordan Hubbard not be used in advertising or publicity
- X * pertaining to distribution of the software without specific, written
- X * prior permission.
- X *
- X */
- X
- X/*
- X * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
- X *
- X * All Rights Reserved
- X *
- X * Permission to use, copy, modify, and distribute this software and its
- X * documentation for any purpose and without fee is hereby granted,
- X * provided that the above copyright notice appear in all copies and that
- X * both that copyright notice and this permission notice appear in
- X * supporting documentation, and that the name of Digital Equipment
- X * Corporation not be used in advertising or publicity pertaining to
- X * distribution of the software without specific, written prior permission.
- X *
- X *
- X * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- X * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- X * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- X * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- X * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- X * SOFTWARE.
- X */
- X
- X/*
- X * MODIFICATION HISTORY
- X *
- X * 000 -- M. Gancarz, DEC Ultrix Engineering Group
- X * 001 -- Loretta Guarino Reid, DEC Ultrix Engineering Group
- X * Convert to X11
- X * 002 -- Jordan Hubbard, U.C. berkeley.
- X * Added alternate placement of resize window, code for title bar
- X * support.
- X */
- X
- X#include "awm.h"
- X#include "X11/Xutil.h"
- X
- X#define max(a,b) ( (a) > (b) ? (a) : (b) )
- X#define min(a,b) ( (a) > (b) ? (b) : (a) )
- X#define makemult(a, b) ((b==1) ? (a) : (((int)((a) / (b))) * (b)) )
- X
- X/*ARGSUSED*/
- XBoolean Resize(window, mask, button, x0, y0)
- XWindow window; /* Event window. */
- Xint mask; /* Button/key mask. */
- Xint button; /* Button event detail. */
- Xint x0, y0; /* Event mouse position. */
- X{
- X XWindowAttributes client_info; /* client window info. */
- X XWindowAttributes frame_info; /* frame window info */
- X int x1, y1; /* fixed box corner */
- X int x2, y2; /* moving box corner */
- X int x, y;
- X int xinc, yinc;
- X int minwidth, minheight;
- X int maxwidth, maxheight;
- X int ox, oy; /* which quadrant of window */
- X int pop_x, pop_y; /* location of pop window */
- X int hsize, vsize; /* dynamic size */
- X int delta;
- X int junk_x, junk_y;
- X unsigned int ptrmask; /* pointer status word */
- X int num_vectors; /* Number of vectors to XDraw. */
- X Window sub_win; /* Mouse query sub window. */
- X Window root; /* Root query window. */
- X XEvent button_event, *b_ev; /* Button event packet. */
- X XSegment box[MAX_BOX_VECTORS]; /* Box drawing vertex buffer. */
- X XSegment zap[MAX_ZAP_VECTORS]; /* Zap drawing vertex buffer. */
- X Boolean stop; /* Should the window stop changing? */
- X XSizeHints sizehints;
- X XWindowChanges values;
- X int width_offset, height_offset; /* to subtract if resize increments */
- X int x_offset, y_offset; /* add to pointer to get anchor */
- X AwmInfoPtr awi;
- X int (*storegrid_func)(); /* which StoreGrid routine to use */
- X int (*storebox_func)(); /* which StoreBox routing to use */
- X int buttonConfirmEvent;
- X extern void ungrab_pointer();
- X extern void grab_pointer();
- X
- X Entry("Resize")
- X
- X /*
- X * Do nothing if the event window is the root window.
- X */
- X if (window == RootWindow(dpy, scr))
- X Leave(FALSE)
- X
- X /*
- X * Gather info about the event window.
- X */
- X awi = GetAwmInfo(window);
- X if (!awi)
- X Leave(FALSE)
- X /*
- X * Do not resize an icon window.
- X */
- X if (window == awi->icon)
- X Leave(FALSE)
- X
- X window = awi->client;
- X b_ev = &button_event;
- X buttonConfirmEvent = ButtonRelease;
- X
- X status = XGetWindowAttributes(dpy, window, &client_info);
- X if (status == FAILURE)
- X Leave(FALSE)
- X
- X if (awi->frame) { /* we have to compensate */
- X status = XGetWindowAttributes(dpy, awi->frame, &frame_info);
- X client_info.y = frame_info.y;
- X client_info.x = frame_info.x;
- X if (status == FAILURE)
- X Leave(FALSE)
- X if (DECORATED(awi)) {
- X if (awi->title)
- X client_info.y += titleHeight + 2;
- X if (awi->attrs & AT_BORDER) {
- X client_info.x += BContext + 1;
- X if (!awi->title)
- X client_info.y += BContext + 1;
- X }
- X }
- X }
- X
- X /*
- X * Clear The vector buffers.
- X */
- X bzero(box, sizeof(box));
- X if (Zap)
- X bzero(zap, sizeof(zap));
- X storegrid_func = StoreGridBox;
- X storebox_func = StoreBox;
- X
- X /*
- X * If we are here then we have a resize operation in progress.
- X */
- X
- X /*
- X * Turn on the resize cursor.
- X */
- X grab_pointer();
- X /*
- X * calculate fixed point (x1, y1) and varying point (x2, y2).
- X */
- X hsize = client_info.width;
- X vsize = client_info.height;
- X x1 = client_info.x;
- X y1 = client_info.y;
- X x2 = x1 + hsize;
- X y2 = y1 + vsize;
- X
- X /*
- X * Get the event window resize hint.
- X */
- X sizehints.flags = 0;
- X XGetSizeHints(dpy, window, &sizehints, XA_WM_NORMAL_HINTS);
- X CheckConsistency(&sizehints);
- X
- X /* until there are better WM_HINTS, we'll assume that the client's
- X * minimum width and height are the appropriate offsets to subtract
- X * when resizing with an explicit resize increment.
- X */
- X if ((sizehints.flags & PMinSize) && (sizehints.flags & PResizeInc)) {
- X width_offset = sizehints.min_width;
- X height_offset = sizehints.min_height;
- X } else
- X width_offset = height_offset = 0;
- X
- X /*
- X * decide what resize mode we are in. Always rubberband if window
- X * is too small.
- X */
- X if (client_info.width > 2 && client_info.height > 2) {
- X ox = ((x0 - client_info.x) * 3) / client_info.width;
- X oy = ((y0 - client_info.y) * 3) / client_info.height;
- X if ((ox + oy) & 1) {
- X if (ox & 1) {
- X /* fix up size hints so that we will never change width */
- X sizehints.min_width = sizehints.max_width =
- X client_info.width;
- X if ((sizehints.flags & PMinSize) == 0) {
- X sizehints.min_height = 0;
- X sizehints.flags |= PMinSize;
- X }
- X if ((sizehints.flags & PMaxSize) == 0) {
- X sizehints.max_height = DisplayHeight(dpy, scr);
- X sizehints.flags |= PMaxSize;
- X }
- X }
- X if (oy & 1) {
- X /* fix up size hints so that we will never change height */
- X sizehints.min_height = sizehints.max_height =
- X client_info.height;
- X if ((sizehints.flags & PMinSize)==0) {
- X sizehints.min_width = 0;
- X sizehints.flags |= PMinSize;
- X }
- X if ((sizehints.flags & PMaxSize)==0) {
- X sizehints.max_width = DisplayWidth(dpy, scr);
- X sizehints.flags |= PMaxSize;
- X }
- X }
- X }
- X }
- X else ox = oy = 2;
- X /* change fixed point to one that shouldn't move */
- X if (oy == 0) {
- X y = y1; y1 = y2; y2 = y;
- X }
- X if (ox == 0) {
- X x = x1; x1 = x2; x2 = x;
- X }
- X if (sizehints.flags & PMinSize) {
- X minwidth = sizehints.min_width;
- X minheight = sizehints.min_height;
- X } else {
- X minwidth = 0;
- X minheight = 0;
- X }
- X if (sizehints.flags & PMaxSize) {
- X maxwidth = max(sizehints.max_width, minwidth);
- X maxheight = max(sizehints.max_height, minheight);
- X } else {
- X maxwidth = DisplayWidth(dpy, scr);
- X maxheight = DisplayHeight(dpy, scr);
- X }
- X if (sizehints.flags & PResizeInc) {
- X xinc = sizehints.width_inc;
- X yinc = sizehints.height_inc;
- X } else {
- X xinc = 1;
- X yinc = 1;
- X }
- X switch (ox) {
- X case 0:
- X pop_x = x1 - PWidth;
- X break;
- X case 1:
- X pop_x = x1 + (hsize - PWidth) / 2;
- X break;
- X case 2:
- X pop_x = x1;
- X break;
- X }
- X switch (oy) {
- X case 0:
- X pop_y = y1 - PHeight;
- X break;
- X case 1:
- X pop_y = y1 + (vsize - PHeight) / 2;
- X break;
- X case 2:
- X pop_y = y1;
- X break;
- X }
- X /*
- X * Double expose on the target window is too expensive for some reason
- X * or another. Paint the popup window in the upper left hand
- X * corner of the screen if RootResizeBox is FALSE. This is also
- X * more-or-less consistent with the position of the map request popup.
- X */
- X if (RootResizeBox == TRUE)
- X values.x = values.y = 0;
- X else {
- X if (pop_x < 0 || pop_x > (DisplayWidth(dpy, scr) - PWidth))
- X pop_x = 0;
- X if (pop_y < 0 || pop_y > (DisplayHeight(dpy, scr) - PHeight))
- X pop_y = 0;
- X values.x = pop_x;
- X values.y = pop_y;
- X }
- X values.stack_mode = Above;
- X XConfigureWindow(dpy, Pop, (unsigned int) CWX|CWY|CWStackMode, &values);
- X XMapWindow(dpy, Pop);
- X if (Grid) {
- X num_vectors = (*storegrid_func)(box,
- X MIN(x1, x2), MIN(y1, y2),
- X MAX(x1, x2), MAX(y1, y2));
- X }
- X else {
- X num_vectors = (*storebox_func)(box,
- X MIN(x1, x2), MIN(y1, y2),
- X MAX(x1, x2), MAX(y1, y2));
- X }
- X
- X /*
- X * If we freeze the server, then we will draw solid
- X * lines instead of flickering ones during resizing.
- X */
- X if (Freeze)
- X XGrabServer(dpy);
- X /* protect us from ourselves */
- X Snatched = True;
- X /*
- X * Process any pending exposure events before drawing the box.
- X */
- X while (QLength(dpy) > 0) {
- X XPeekEvent(dpy, b_ev);
- X if (b_ev->xany.window == RootWindow(dpy, scr))
- X break;
- X GetButton(b_ev);
- X }
- X if (ResizeRelative) {
- X x_offset = x2 - x0;
- X y_offset = y2 - y0;
- X }
- X else
- X x_offset = y_offset = 0;
- X
- X /*
- X * Now draw the box.
- X */
- X DrawBox();
- X Frozen = window;
- X
- X stop = FALSE;
- X x = -1; y = -1;
- X
- X while (!stop) {
- X if (x != x2 || y != y2) {
- X x = x2; y = y2;
- X
- X /*
- X * If we've frozen the server, then erase
- X * the old box.
- X */
- X if (Freeze)
- X DrawBox();
- X
- X if (Grid) {
- X num_vectors = (*storegrid_func)(box,
- X MIN(x1, x), MIN(y1, y),
- X MAX(x1, x), MAX(y1, y));
- X }
- X else {
- X num_vectors = (*storebox_func)(box,
- X MIN(x1, x), MIN(y1, y),
- X MAX(x1, x), MAX(y1, y));
- X }
- X
- X if (Freeze)
- X DrawBox();
- X
- X {
- X int Hsize = (hsize - width_offset) / xinc;
- X int Vsize = (vsize - height_offset) / yinc;
- X int pos = 4;
- X PText[0] = (Hsize>99) ? (Hsize / 100 + '0') : ' ';
- X PText[1] = (Hsize>9) ? ((Hsize / 10) % 10 + '0') : ' ';
- X PText[2] = Hsize % 10 + '0';
- X if (Vsize>99) PText[pos++] = Vsize / 100 + '0';
- X if (Vsize>9) PText[pos++] = (Vsize / 10) % 10 + '0';
- X PText[pos++] = Vsize % 10 + '0';
- X while (pos<7) PText[pos++] = ' ';
- X }
- X /*
- X * If the font is not fixed width we have to
- X * clear the window to guarantee that the characters
- X * that were there before are erased.
- X */
- X if (!(PFontInfo->per_char))
- X XClearWindow(dpy, Pop);
- X XDrawImageString(
- X dpy, Pop, PopGC,
- X PPadding, PPadding+PFontInfo->ascent,
- X PText, PTextSize);
- X }
- X if (!Freeze) {
- X DrawBox();
- X DrawBox();
- X }
- X
- X if (XPending(dpy) && !ProcessRequests(box, num_vectors) &&
- X GetButton(b_ev)) {
- X if ((b_ev->xany.type != ButtonPress) &&
- X (b_ev->xany.type != ButtonRelease))
- X continue; /* spurious menu event... */
- X
- X if (Freeze) {
- X DrawBox();
- X Frozen = (Window)0;
- X XUngrabServer(dpy);
- X }
- X
- X if (b_ev->xany.type == buttonConfirmEvent &&
- X b_ev->xbutton.button == button)
- X stop = TRUE;
- X else {
- X XUnmapWindow(dpy, Pop);
- X ResetCursor(button);
- X Snatched = False;
- X ungrab_pointer();
- X Leave(TRUE)
- X }
- X }
- X else {
- X XQueryPointer(dpy, RootWindow(dpy, scr), &root,
- X &sub_win, &x2, &y2, &junk_x, &junk_y, &ptrmask);
- X x2 += x_offset; /* get to anchor point */
- X y2 += y_offset;
- X }
- X hsize = max(min(abs (x2 - x1), maxwidth), minwidth);
- X hsize = makemult(hsize - minwidth, xinc) + minwidth;
- X
- X vsize = max(min(abs(y2 - y1), maxheight), minheight);
- X vsize = makemult(vsize - minheight, yinc) + minheight;
- X if (sizehints.flags & PAspect) {
- X if ((hsize * sizehints.max_aspect.y >
- X vsize * sizehints.max_aspect.x)) {
- X delta = makemult((hsize * sizehints.max_aspect.y /
- X sizehints.max_aspect.x) - vsize,
- X yinc);
- X if ((vsize + delta <= maxheight))
- X vsize += delta;
- X else {
- X delta = makemult(hsize -
- X (sizehints.max_aspect.x *
- X vsize/sizehints.max_aspect.y),
- X xinc);
- X if (hsize - delta >= minwidth)
- X hsize -= delta;
- X }
- X }
- X if (hsize * sizehints.min_aspect.y < vsize *
- X sizehints.min_aspect.x) {
- X delta = makemult((sizehints.min_aspect.x *
- X vsize/sizehints.min_aspect.y) - hsize,
- X xinc);
- X if (hsize + delta <= maxwidth)
- X hsize += delta;
- X else {
- X delta = makemult(vsize -
- X (hsize*sizehints.min_aspect.y /
- X sizehints.min_aspect.x),
- X yinc);
- X if (vsize - delta >= minheight)
- X vsize -= delta;
- X }
- X }
- X
- X }
- X if (ox == 0)
- X x2 = x1 - hsize;
- X else
- X x2 = x1 + hsize;
- X
- X if (oy == 0)
- X y2 = y1 - vsize;
- X else
- X y2 = y1 + vsize;
- X
- X }
- X if (x2 < x1) {
- X x = x1; x1 = x2; x2 = x;
- X }
- X if (y2 < y1) {
- X y = y1; y1 = y2; y2 = y;
- X }
- X XUnmapWindow(dpy, Pop);
- X if ((x1 !=client_info.x) || (y1 != client_info.y) ||
- X (hsize != client_info.width) ||
- X (vsize != client_info.height)) {
- X XWindowChanges xwc;
- X
- X xwc.x = x1;
- X xwc.y = y1;
- X xwc.width = hsize;
- X xwc.height = vsize;
- X ConfigureWindow(window,
- X (unsigned int) CWX | CWY | CWHeight | CWWidth, &xwc);
- X }
- X Snatched = False;
- X ungrab_pointer();
- X Leave(TRUE)
- X}
- X
- XCheckConsistency(hints)
- XXSizeHints *hints;
- X{
- X Entry("CheckConsistency")
- X
- X if (hints->min_height < 0)
- X hints->min_height = 0;
- X if (hints->min_width < 0)
- X hints->min_width = 0;
- X
- X if (hints->max_height <= 0 || hints->max_width <= 0)
- X hints->flags &= ~PMaxSize;
- X
- X hints->min_height = min(DisplayHeight(dpy, scr), hints->min_height);
- X hints->min_width = min(DisplayWidth(dpy, scr), hints->min_width);
- X
- X hints->max_height = min(DisplayHeight(dpy, scr), hints->max_height);
- X hints->max_width = min(DisplayWidth(dpy, scr), hints->max_width);
- X
- X if ((hints->flags & PMinSize) && (hints->flags & PMaxSize) &&
- X ((hints->min_height > hints->max_height) ||
- X (hints->min_width > hints->max_width)))
- X hints->flags &= ~(PMinSize|PMaxSize);
- X
- X if ((hints->flags & PAspect) &&
- X (hints->min_aspect.x * hints->max_aspect.y >
- X hints->max_aspect.x * hints->min_aspect.y))
- X hints->flags &= ~(PAspect);
- X Leave_void
- X}
- END_OF_FILE
- if test 15574 -ne `wc -c <'Resize.c'`; then
- echo shar: \"'Resize.c'\" unpacked with wrong size!
- fi
- # end of 'Resize.c'
- fi
- if test -f 'menus/menu.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'menus/menu.c'\"
- else
- echo shar: Extracting \"'menus/menu.c'\" \(33843 characters\)
- sed "s/^X//" >'menus/menu.c' <<'END_OF_FILE'
- X
- X#ifndef lint
- X static char sccs_id[] = "@(#)menu.c 2.1 12/16/87 Siemens Corporate Research and Support, Inc.";
- X#endif
- X
- X
- X/*
- X RTL Menu Package Version 1.0
- X by Joe Camaratta and Mike Berman, Siemens RTL, Princeton NJ, 1987
- X
- X menu.c: menu utility and support functions.
- X
- X Originally hacked by Adam J. Richter, based on the menu package for xterm.
- X ( misc.c X10/6.6 )
- X
- X */
- X
- X/*
- X *
- X * Changed in various and subtle ways by Jordan Hubbard, Ardent Computer.
- X * February 1st, 1988: Removed dependence on oldX by nuking AssocTable
- X * stuff in favor of contexts. Added "label" panes, useful for titling
- X * purposes. Variable height items, variable fonts, pictoral panes
- X * (pixmaps) for cute graphic menus.
- X */
- X
- X/*
- X *
- X * Copyright 1987, 1988 by Ardent Computer Corporation, Sunnyvale, Ca.
- X *
- X * Copyright 1987 by Jordan Hubbard.
- X *
- X *
- X * All Rights Reserved
- X *
- X * Permission to use, copy, modify, and distribute this software and its
- X * documentation for any purpose and without fee is hereby granted,
- X * provided that the above copyright notice appear in all copies and that
- X * both that copyright notice and this permission notice appear in
- X * supporting documentation, and that the name of Ardent Computer
- X * Corporation or Jordan Hubbard not be used in advertising or publicity
- X * pertaining to distribution of the software without specific, written
- X * prior permission.
- X *
- X */
- X
- X
- X/*
- X
- X Copyright 1987 by
- X Siemens Corporate Research and Support, Inc., Princeton, New Jersey
- X
- X Permission to use, copy, modify, and distribute this software
- X and its documentation for any purpose and without fee is
- X hereby granted, provided that the above copyright notice
- X appear in all copies and that both that copyright notice and
- X this permission notice appear in supporting documentation, and
- X that the name of Siemens not be used in advertising or
- X publicity pertaining to distribution of the software without
- X specific, written prior permission. Siemens makes no
- X representations about the suitability of this software for any
- X purpose. It is provided "as is" without express or implied
- X warranty.
- X
- X */
- X
- X/*
- X
- X Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
- X
- X Permission to use, copy, modify, and distribute this
- X software and its documentation for any purpose and without
- X fee is hereby granted, provided that the above copyright
- X notice appear in all copies and that both that copyright
- X notice and this permission notice appear in supporting
- X documentation, and that the name of M.I.T. not be used in
- X advertising or publicity pertaining to distribution of the
- X software without specific, written prior permission.
- X M.I.T. makes no representations about the suitability of
- X this software for any purpose. It is provided "as is"
- X without express or implied warranty.
- X
- X */
- X
- X/*
- X * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
- X *
- X * All Rights Reserved
- X *
- X * Permission to use, copy, modify, and distribute this software and its
- X * documentation for any purpose and without fee is hereby granted,
- X * provided that the above copyright notice appear in all copies and that
- X * both that copyright notice and this permission notice appear in
- X * supporting documentation, and that the name of Digital Equipment
- X * Corporation not be used in advertising or publicity pertaining to
- X * distribution of the software without specific, written prior permission.
- X *
- X *
- X * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- X * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- X * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- X * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- X * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- X * SOFTWARE.
- X */
- X
- X/* Got that? Good! Now, there is actually some code in here.. */
- X
- X
- X#include <stdio.h>
- X#include "X11/Xlib.h"
- X#include "X11/cursorfont.h"
- X#include "X11/Xutil.h"
- X#include "X11/Intrinsic.h"
- X
- X#include "menu.h"
- X#include "menu.def.h"
- X#include "gray1.h"
- X#include "arrow_icon.h"
- X#include "dbug.h"
- X
- X#define MakeEven(x) ((x%2 == 0)? x : x-1)
- X
- X
- X#define InvertPlane 1
- X
- Xstatic char Check_MarkBits[] = {
- X 0x00, 0x01, 0x80, 0x01, 0xc0, 0x00, 0x60, 0x00,
- X 0x31, 0x00, 0x1b, 0x00, 0x0e, 0x00, 0x04, 0x00
- X };
- X
- XMenu MenuDefault;
- X
- X/*
- X * the following have already been set my GetDefaults()
- X * by the time we get here.
- X */
- XXFontStruct *MFontInfo;
- XXFontStruct *MBoldFontInfo;
- Xint MBorderWidth, MPad, MDelta, MItemBorder;
- XPixel MForeground, MBackground, MBorder;
- X
- Xextern Boolean SaveUnder;
- Xextern int Reverse;
- Xextern Display *dpy;
- Xextern int scr;
- X
- Xstatic XContext Menu_context;
- Xstatic XContext Item_context;
- Xstatic contexts_created = FALSE;
- X
- XMenuItem *AddMenuItem(), *Display_Menu(), *MenuGetItem(),
- X *MenuItemByName(), *MenuItemByData(), *GetInitialItem(), *MoveMenu();
- XBoolean DisposeItem(), SetItemCheck(), SetItemDisable(), Recalc_Menu(),
- X SetupItems(), MapMenu(), SetItemText(), SetupMenuWindow();
- Xvoid DisposeMenu(), InitMenu(), Undisplay_Menu(), MenuInvert(),
- X PlacePointer(), Draw_Menu(), Draw_Item(), SetInitialItem(),
- X ClearInitialItem(), Generate_Menu_Entries(), UnmapMenu(),
- X SetInputMask();
- XMenu *NewMenu(), *MenuGetMenu();
- Xint ItemGetMiddleY();
- X
- X/*
- X * AddMenuItem() adds a menu item to an existing menu, at the end of the
- X * list, which are number sequentially from zero. The menuitem index is
- X * return, or -1 if failed.
- X */
- X
- XMenuItem *AddMenuItem(menu, text, bitmap_file)
- XMenu *menu;
- Xchar *text;
- Xchar *bitmap_file;
- X{
- X MenuItem *menuitem, **next;
- X int junk;
- X char *data;
- X
- X Entry("AddMenuItem")
- X
- X if (!menu || (!text && !bitmap_file) || (menuitem = allocate(MenuItem, 1))
- X == (MenuItem *)0)
- X Leave(NULLITEM)
- X bzero((char *)menuitem, sizeof(MenuItem));
- X ItemText(menuitem) = allocate(char, (strlen(text) + 1));
- X strcpy(ItemText(menuitem), text);
- X ItemTextLength(menuitem) = strlen(text);
- X if (bitmap_file) {
- X bitmap_file = (char *)expand_from_path(bitmap_file);
- X if (XmuReadBitmapDataFromFile(bitmap_file,
- X &(menuitem->itemTextWidth),
- X &(menuitem->itemHeight),
- X &data,
- X &junk, &junk) != BitmapSuccess) {
- X fprintf(stderr, "awm: Can't read bitmap file '%s'\n",
- X bitmap_file);
- X exit(1);
- X }
- X menuitem->itemBackground =
- X XCreatePixmapFromBitmapData(dpy, RootWindow(dpy, scr),
- X data,
- X menuitem->itemTextWidth,
- X menuitem->itemHeight,
- X MForeground,
- X MBackground,
- X DefaultDepth(dpy, scr));
- X if (!menuitem->itemBackground) {
- X fprintf(stderr, "awm: Can't create pixmap for file '%s'\n",
- X bitmap_file);
- X exit(1);
- X }
- X free(data);
- X free(bitmap_file);
- X }
- X for(next = &menu->menuItems; *next; next = &(*next)->nextItem);
- X
- X *next = menuitem;
- X
- X SetMenuFlag(menu, menuChanged);
- X Leave(menuitem)
- X}
- X
- X/*
- X * DisposeItem() releases the memory allocated for the given indexed
- X * menuitem. Nonzero is returned if an item was actual disposed of.
- X * It also checks to see whether the item we're disposing is the
- X * initial item for the menu -- if so, null out the initial item.
- X */
- XBoolean DisposeItem(menu, item)
- XMenu *menu;
- XMenuItem *item;
- X{
- X MenuItem **next, **last, *menuitem;
- X
- X Entry("DisposeItem")
- X
- X if (MenuIsNull(menu) || ItemIsNull(item))
- X Leave(FALSE)
- X next = &MenuItems(menu);
- X do {
- X if(!*next)
- X Leave(FALSE)
- X last = next;
- X next = &(*next)->nextItem;
- X } while((*last != item) && !ItemIsNull(*next));
- X menuitem = *last;
- X *last = *next;
- X if (ItemWindow(menuitem)) {
- X XDeleteContext(dpy, ItemWindow(menuitem), Item_context);
- X XDestroyWindow(dpy, ItemWindow(menuitem));
- X }
- X if (ItemIsInitialItem(menu, menuitem))
- X ClearInitialItem(menu);
- X
- X if (ItemText(menuitem))
- X free((char*)ItemText(menuitem));
- X free((char*)menuitem);
- X
- X SetMenuFlag(menu, menuChanged);
- X Leave(TRUE)
- X}
- X
- X/*
- X * DisposeMenu() releases the memory allocated for the given menu.
- X */
- Xvoid DisposeMenu(menu)
- XMenu *menu;
- X{
- X Entry("DisposeMenu")
- X
- X if(!menu)
- X Leave_void
- X if (TestMenuFlag(menu, menuMapped))
- X UnmapMenu(menu);
- X while(DisposeItem(menu, MenuItems(menu)));
- X if(MenuWindow(menu)) {
- X XDeleteContext(dpy, MenuWindow(menu), Menu_context);
- X XDestroyWindow(dpy, MenuWindow(menu));
- X }
- X XFreePixmap (dpy, MenuGreyPixmap(menu));
- X XFreePixmap (dpy, MenuArrowPixmap(menu));
- X XFreePixmap (dpy, MenuCheckmarkPixmap(menu));
- X XFreeGC (dpy, MenuNormalGC(menu));
- X XFreeGC (dpy, MenuInvertGC(menu));
- X XFreeGC (dpy, menu->boldGC);
- X
- X if (MenuHasInitialItem(menu))
- X ClearInitialItem(menu);
- X free((char*) menu);
- X Leave_void
- X}
- X
- Xstatic char *Name;
- X
- Xvoid InitMenu(name, options)
- Xchar *name;
- Xunsigned int options;
- X{
- X char *cp;
- X
- X Entry("InitMenu")
- X
- X Name = name;
- X MenuDefault.menuFlags = menuChanged;
- X
- X MenuDefault.menuInitialItemText = (char *) NULL;
- X MenuDefault.display = dpy;
- X MenuDefault.screen = scr;
- X MenuDefault.menuOptions = options;
- X Leave_void
- X}
- X
- X/*
- X * ItemText changes the text of item of the menu.
- X */
- XBoolean SetItemText(menu, item, text)
- XMenu *menu;
- XMenuItem *item;
- Xchar *text;
- X{
- X Entry("SetItemText")
- X
- X if (strcmp (ItemText(item), text) == 0)
- X Leave (True)
- X
- X if(ItemText(item))
- X free((char *) ItemText(item));
- X
- X ItemText(item) = allocate(char, (strlen(text) + 1));
- X strcpy(ItemText(item), text);
- X
- X ItemTextLength(item) = strlen (text);
- X SetMenuFlag(menu, menuChanged);
- X
- X (void) Recalc_Menu (menu);
- X Leave(TRUE)
- X}
- X
- X/*
- X * NewMenu() returns a pointer to an initialized new Menu structure, or NULL
- X * if failed.
- X *
- X * The Menu structure _menuDefault contains the default menu settings.
- X */
- XMenu *NewMenu()
- X{
- X extern Pixmap MakeGreyStipple ();
- X Menu *menu = 0;
- X
- X XGCValues gcValues;
- X
- X static unsigned long gcMask =
- X (GCFunction | GCForeground | GCBackground | GCFont | GCStipple |
- X GCSubwindowMode | GCGraphicsExposures);
- X
- X char *cp;
- X
- X Entry("NewMenu")
- X
- X /*
- X * Allocate the memory for the menu structure.
- X */
- X if(MenuIsNull((menu = allocate(Menu, 1))))
- X Leave(NULLMENU)
- X
- X /*
- X * Initialize to default values.
- X */
- X *menu = MenuDefault;
- X gcValues.font = MFontInfo->fid;
- X
- X /*
- X * If the menu cursor hasn't been given, make a default one.
- X */
- X
- X MenuCursor(menu) = XCreateFontCursor (dpy, XC_right_ptr);
- X MenuArrowPixmap(menu) = XCreatePixmapFromBitmapData(dpy,
- X RootWindow(dpy, scr),
- X arrow_bits,
- X arrow_width,
- X arrow_height,
- X MForeground,
- X MBackground,
- X DefaultDepth(dpy, scr));
- X
- X MenuGreyPixmap(menu) = XCreateBitmapFromData(dpy,
- X RootWindow(dpy, scr),
- X gray1_bits,
- X gray1_width, gray1_height);
- X
- X MenuCheckmarkPixmap(menu) = XCreatePixmapFromBitmapData(dpy,
- X RootWindow(dpy, scr),
- X Check_MarkBits,
- X checkMarkWidth,
- X checkMarkHeight,
- X MForeground,
- X MBackground,
- X DefaultDepth(dpy, scr));
- X
- X gcValues.foreground = MForeground;
- X gcValues.background = MBackground;
- X
- X gcValues.stipple = MenuGreyPixmap(menu);
- X gcValues.function = GXcopy;
- X gcValues.subwindow_mode = IncludeInferiors;
- X gcValues.graphics_exposures = False;
- X MenuNormalGC(menu) =
- X XCreateGC (dpy, RootWindow(dpy, scr),
- X gcMask,
- X &gcValues);
- X /* reverse */
- X gcValues.foreground = MBackground;
- X gcValues.background = MForeground;
- X
- X MenuInvertGC(menu) = XCreateGC(dpy, RootWindow (dpy, scr),
- X gcMask,
- X &gcValues);
- X gcValues.foreground = MForeground;
- X gcValues.background = MBackground;
- X gcValues.font = MBoldFontInfo->fid;
- X menu->boldGC = XCreateGC(dpy, RootWindow(dpy, scr),
- X gcMask,
- X &gcValues);
- X Leave(menu)
- X}
- X
- X
- X/*
- X * SetItemCheck sets the check state of item of the menu to "state".
- X */
- XBoolean SetItemCheck(menu, item, state)
- XMenu *menu;
- XMenuItem *item;
- Xint state;
- X{
- X Entry("SetItemCheck")
- X
- X if (TestItemFlag(item,itemChecked) == state) /* Exit if unchanged */
- X Leave (True)
- X
- X if (state)
- X SetItemFlag(item, itemChecked);
- X else
- X ResetItemFlag(item, itemChecked);
- X
- X SetItemFlag(item, itemChanged);
- X SetMenuFlag(menu, menuItemChanged);
- X
- X Leave(TRUE)
- X}
- X/*
- X * SetItemDeaf sets the "deaf" state of item of the menu to "state".
- X * "deaf" means that the item is display only and not sensitive to input.
- X */
- XBoolean SetItemDeaf(menu, item, state)
- XMenu *menu;
- XMenuItem *item;
- Xint state;
- X{
- X Entry("SetItemDeaf")
- X
- X if (TestItemFlag(item,itemDeaf) == state) /* Exit if unchanged */
- X Leave (True)
- X
- X if (state)
- X SetItemFlag(item, itemDeaf);
- X else
- X ResetItemFlag(item, itemDeaf);
- X
- X SetItemFlag(item, itemChanged);
- X SetMenuFlag(menu, menuItemChanged);
- X if (ItemIsInitialItem(menu, item))
- X ClearInitialItem(menu);
- X Leave(TRUE)
- X}
- X
- X/*
- X * SetItemDisable sets the disable state of item "n" of the menu to "state".
- X */
- XBoolean SetItemDisable(menu, item, state)
- XMenu *menu;
- XMenuItem *item;
- Xint state;
- X{
- X Entry("SetItemDisable")
- X
- X if (TestItemFlag(item,itemDisabled) == state) /* Exit if unchanged */
- X Leave (True)
- X
- X if(state)
- X {
- X SetItemFlag(item, itemDisabled);
- X /* if disabled item is currently initial item, null initial item */
- X if (ItemIsInitialItem(menu, item))
- X ClearInitialItem(menu);
- X }
- X else
- X ResetItemFlag(item, itemDisabled);
- X
- X SetItemFlag(item, itemChanged);
- X SetMenuFlag(menu, menuItemChanged);
- X
- X Leave(TRUE)
- X}
- X
- XMenuItem *Display_Menu(menu, parent, x, y)
- XMenu *menu;
- XMenu *parent;
- Xint x;
- Xint y;
- X{
- X MenuItem *item;
- X
- X Entry("Display_Menu")
- X
- X if (MenuIsNull(menu))
- X Leave(FALSE)
- X
- X MenuParent(menu) = parent;
- X
- X if (MenuIsNull(parent))
- X MenuNested(menu) = 0;
- X else
- X MenuNested(menu) = MenuNested(parent) + 1;
- X if (!MenuWindow(menu) || TestMenuFlag(menu,
- X (menuChanged | menuItemChanged))) {
- X if (!SetupMenuWindow(menu))
- X Leave(NULL)
- X Generate_Menu_Entries(menu);
- X }
- X if (TestOptionFlag(menu,savebits) &&
- X (MenuSavedPixmap(menu) != (Pixmap) 0))
- X SetInputMask(menu, MenuIgnoreMask);
- X else
- X SetInputMask(menu, ExposureMask);
- X if (!(item = MoveMenu(menu, x, y)) || !MapMenu(menu))
- X Leave(FALSE)
- X Draw_Menu(menu);
- X
- X Leave(item)
- X}
- X
- Xvoid Undisplay_Menu(menu)
- XMenu *menu;
- X{
- X Entry("Undisplay_Menu")
- X
- X if (MenuIsNull(menu))
- X Leave_void
- X
- X MenuParent(menu) = NULLMENU;
- X MenuNested(menu) = 0;
- X
- X UnmapMenu(menu);
- X Leave_void
- X}
- X
- Xvoid MenuInvert(menu, item)
- XMenu *menu;
- XMenuItem *item;
- X{
- X Entry("MenuInvert")
- X
- X XFillRectangle(dpy,
- X ItemWindow(item),
- X MenuInvertGC(menu),
- X 0, 0,
- X MenuWidth(menu),
- X item->itemHeight);
- X Leave_void
- X}
- X
- X/*
- X * Recalculate all of the various menu and item variables.
- X */
- XBoolean Recalc_Menu(menu)
- XMenu *menu;
- X{
- X MenuItem *item;
- X int max, height, fontheight, boldfontheight, nitems;
- X /* Gets set to false first time we see an item with text */
- X unsigned int menuIsPictures = TRUE;
- X
- X Entry("Recalc_Menu")
- X
- X /*
- X * We must have already gotten the menu font.
- X */
- X if(!MFontInfo)
- X Leave(FALSE)
- X /*
- X * Initialize the various max width variables.
- X */
- X fontheight = MFontInfo->ascent + MFontInfo->descent + 2;
- X boldfontheight = MBoldFontInfo->ascent + MBoldFontInfo->descent + 2;
- X height = nitems = 0;
- X MenuMaxTextWidth(menu) = 0;
- X /*
- X * The item height is the maximum of the font height and the
- X * checkbox height, unless we find out that it's a pixmap (in which
- X * case, most of these values are overridden).
- X */
- X max = fontheight;
- X if(checkMarkHeight > max)
- X max = checkMarkHeight;
- X
- X max += 2*MItemBorder;
- X max = MakeEven(max);
- X
- X /*
- X * Go through the menu item list.
- X */
- X for(item = MenuItems(menu) ; item ; item = ItemNext(item)) {
- X if (item->itemBackground) /* pixmap is static size */
- X max = item->itemHeight;
- X else {
- X if (ItemIsDeaf(item)) /* It's a label, use bold info */
- X max = boldfontheight;
- X else
- X max = fontheight;
- X }
- X if (checkMarkHeight > max)
- X max = checkMarkHeight;
- X if (!item->itemBackground) {
- X max += 2 * MItemBorder;
- X max = MakeEven(max);
- X item->itemHeight = max;
- X }
- X height += max;
- X nitems++;
- X /*
- X * Check the text width with the max value stored in
- X * menu.
- X */
- X if (!item->itemBackground) {
- X if ((ItemTextWidth(item) = XTextWidth(ItemIsDeaf(item) ?
- X MBoldFontInfo
- X : MFontInfo,
- X ItemText(item),
- X strlen (ItemText(item))))
- X > MenuMaxTextWidth(menu))
- X MenuMaxTextWidth(menu) = ItemTextWidth(item);
- X menuIsPictures = FALSE;
- X }
- X /* ItemTextWidth is really pixmap size. Yick. */
- X else {
- X if (ItemTextWidth(item) > MenuMaxTextWidth(menu))
- X MenuMaxTextWidth(menu) = ItemTextWidth(item);
- X }
- X
- X }
- X /*
- X * Set the menu height and then set the menu width.
- X */
- X MenuHeight(menu) = height;
- X menu->avgHeight = height / nitems;
- X
- X if (menuIsPictures == TRUE)
- X MenuWidth(menu) = MenuMaxTextWidth(menu) + (2 * MItemBorder);
- X else {
- X MenuWidth(menu) = 4 * MenuItemPad(menu) + MenuMaxTextWidth(menu) +
- X checkMarkWidth + arrow_width + (2 * MItemBorder);
- X }
- X MenuItemWidth(menu) = MenuWidth(menu) - (2 * MItemBorder);
- X Leave(TRUE)
- X}
- X
- X/*
- X * Figure out where to popup the menu, relative to the where the button was
- X * pressed.
- X * Returns pointer to initial item to warp to.
- X */
- Xstatic MenuItem *MoveMenu(menu, ev_x, ev_y)
- XMenu *menu;
- Xint ev_x, ev_y;
- X{
- X int x, y;
- X int total_width, total_height;
- X int offset;
- X MenuItem *item;
- X Window junk;
- X int r_x, foo, state;
- X
- X Entry("MoveMenu")
- X
- X /*
- X * Get the coordinates of the mouse when the button was pressed.
- X */
- X
- X total_width = MenuWidth(menu) + 2 * MenuBorderWidth(menu);
- X total_height = MenuHeight(menu) + 2 * MenuBorderWidth(menu);
- X
- X XQueryPointer(dpy, RootWindow(dpy, scr), &junk, &junk, &r_x, &y,
- X &foo, &foo, &state);
- X x = ev_x - MenuItemPad(menu);
- X if (x < 0)
- X x = 0;
- X else if (TestOptionFlag(menu, rightoffset) &&
- X !MenuIsNull(MenuParent(menu)))
- X {
- X /* check whether parent is close to right edge... */
- X /* "too close" means that child would leave < delta of its parent */
- X /* visible to its left. */
- X if (TestOptionFlag(menu, bigoffset))
- X {
- X if (MenuX(MenuParent(menu)) + MenuWidth(MenuParent(menu)) >
- X DisplayWidth(dpy, scr) - total_width)
- X x = MenuX(MenuParent(menu))
- X - total_width + 2*MenuBorderWidth(menu);
- X }
- X else
- X {
- X if (MenuX(MenuParent(menu)) + MenuDelta(MenuParent(menu)) >
- X DisplayWidth(dpy, scr) - total_width)
- X {
- X x = (MenuX(MenuParent(menu)) + MenuWidth(MenuParent(menu)) +
- X 2 * MenuBorderWidth(MenuParent(menu))
- X - total_width - MenuDelta(menu));
- X }
- X }
- X }
- X if (x + total_width >
- X DisplayWidth(dpy, scr))
- X x = DisplayWidth(dpy, scr)
- X - total_width;
- X
- X /*
- X * If we have an initial item, try to popup the menu centered
- X * vertically within this item.
- X */
- X if(MenuHasInitialItem(menu)) {
- X int tmp_y;
- X
- X /*
- X * Look through the item list. "y" is the vertical position
- X * of the top of the current item and "n" is the item number.
- X */
- X offset = MenuBorderWidth(menu);
- X for(item = MenuItems(menu) ; ;) {
- X /*
- X * On finding the initial item, center within this item.
- X */
- X if (ItemIsInitialItem(menu, item)) {
- X y -= offset;
- X break;
- X }
- X else
- X offset += item->itemHeight;
- X /*
- X * If we run out of items, turn off the initial item
- X * and treat this as if no initial item.
- X */
- X if(!(item = ItemNext(item))) {
- X ClearInitialItem(menu);
- X break;
- X }
- X }
- X }
- X
- X if (y < 0)
- X y = 0;
- X else if (y + total_height >
- X DisplayHeight(dpy, scr))
- X {
- X y = DisplayHeight(dpy, scr)
- X - (total_height + 1);
- X }
- X y = MakeEven(y) + 1;
- X XMoveWindow(dpy, MenuWindow(menu), x, y);
- X MenuX(menu) = x;
- X MenuY(menu) = y;
- X
- X if (!ItemIsInitialItem(menu, item))
- X item = MenuItems(menu);
- X Leave(item)
- X}
- X
- X
- Xvoid PlacePointer(menu, item)
- XMenu *menu;
- XMenuItem *item;
- X{
- X int y;
- X
- X Entry("PlacePointer")
- X
- X y = ItemGetMiddleY(item);
- X
- X XWarpPointer(dpy, None,
- X RootWindow(dpy, scr),
- X 0, 0, 0, 0,
- X MenuX(menu) + MPad + (MenuWidth(menu) / 2), y);
- X Leave_void
- X}
- X
- X/*
- X * Map the menu window.
- X */
- Xstatic Boolean MapMenu(menu)
- XMenu *menu;
- X{
- X Entry("MapMenu")
- X
- X if (!TestMenuFlag(menu, menuMapped))
- X MenuItemHighlighted(menu) = NULLITEM;
- X
- X /*
- X * Actually map the window.
- X */
- X
- X if (TestOptionFlag(menu,savebits))
- X {
- X if ((MenuSavedPixmap(menu) == (Pixmap) 0) ||
- X (MenuOldWidth(menu) != MenuWidth(menu)) ||
- X (MenuOldHeight(menu) != MenuHeight(menu)) ||
- X (MenuOldBorderWidth(menu) != MenuBorderWidth(menu)))
- X {
- X if (MenuSavedPixmap(menu) != (Pixmap) 0)
- X XFreePixmap(dpy, MenuSavedPixmap(menu));
- X
- X MenuSavedPixmap(menu) =
- X XCreatePixmap(dpy,
- X RootWindow(dpy, scr),
- X MenuWidth(menu) + 2*MenuBorderWidth(menu),
- X MenuHeight(menu) + 2*MenuBorderWidth(menu),
- X DefaultDepth(dpy, scr));
- X DBUG_5("Pixmaps","Created pixmap: width %d, height %d, depth %d\n",
- X MenuWidth(menu) + 2*MenuBorderWidth(menu),
- X MenuHeight(menu) + 2*MenuBorderWidth(menu),
- X DefaultDepth(dpy, scr));
- X MenuOldWidth(menu) = MenuWidth(menu);
- X MenuOldHeight(menu) = MenuHeight(menu);
- X MenuOldBorderWidth(menu) = MenuBorderWidth(menu);
- X }
- X else
- X SetInputMask(menu, ExposureMask);
- X
- X if (MenuSavedPixmap(menu) != (Pixmap) 0) {
- X /* XFillRectangle(dpy,
- X MenuSavedPixmap(menu),
- X SaveGC,
- X 0,0,
- X MenuWidth(menu) + 2*MenuBorderWidth(menu),
- X MenuHeight(menu) + 2*MenuBorderWidth(menu)); */
- X SetInputMask(menu, MenuIgnoreMask);
- X XCopyArea(dpy,
- X RootWindow(dpy, scr),
- X MenuSavedPixmap(menu),
- X MenuNormalGC(menu),
- X MenuX(menu),
- X MenuY(menu),
- X (unsigned int) (MenuWidth(menu) + 2*MenuBorderWidth(menu)),
- X (unsigned int) (MenuHeight(menu) + 2*MenuBorderWidth(menu)),
- X 0, 0);
- X }
- X else
- X SetInputMask(menu, ExposureMask);
- X
- X }
- X
- X XRaiseWindow(dpy, MenuWindow(menu));
- X XMapWindow(dpy, MenuWindow(menu));
- X SetMenuFlag(menu, menuMapped);
- X Leave(TRUE)
- X}
- X
- Xstatic void Generate_Menu_Entries (menu)
- XMenu *menu;
- X{
- X MenuItem *item;
- X
- X Entry("Generate_Menu_Entries")
- X
- X for (item = MenuItems(menu); item; (item = ItemNext(item))) {
- X
- X if (ItemGenerator(item)) {
- X char *newText;
- X
- X (ItemGenerator(item)) (&newText, &ItemCallback(item));
- X SetItemText (menu, item, newText);
- X }
- X
- X if (ItemCheckproc(item))
- X SetItemCheck (menu, item, (ItemCheckproc(item))(menu,item));
- X }
- X Leave_void
- X}
- X
- X/*
- X * Draw the entire menu in the blank window.
- X */
- Xvoid Draw_Menu(menu)
- XMenu *menu;
- X{
- X MenuItem *item;
- X
- X Entry("Draw_Menu")
- X
- X ResetMenuFlag(menu, menuChanged);
- X /*
- X * For each item in the list, first draw any check mark and then
- X * draw the rest of it.
- X */
- X for(item = MenuItems(menu) ; item ; item = ItemNext(item)) {
- X if (TestOptionFlag(menu, savebits))
- X {
- X /* go ahead and draw it, don't wait for exposes */
- X Draw_Item(menu, item);
- X }
- X }
- X Leave_void
- X}
- X
- X/*
- X * Draw the item at vertical position y.
- X */
- Xvoid Draw_Item(menu, item)
- XMenu *menu;
- XMenuItem *item;
- X{
- X int y; /* baseline */
- X int x = MenuItemPad(menu);
- X int x1 = 2 * MenuItemPad(menu) + checkMarkWidth;
- X int pad;
- X int high;
- X XGCValues gcValues;
- X GC theGC;
- X
- X Entry("Draw_Item")
- X
- X high = (MenuItemHighlighted(menu) == item);
- X theGC = high ? MenuInvertGC(menu) : MenuNormalGC(menu);
- X
- X if (TestItemFlag(item, itemDisabled))
- X {
- X gcValues.fill_style = FillOpaqueStippled;
- X XChangeGC(dpy, theGC, (GCFillStyle), &gcValues);
- X }
- X
- X if (!item->itemBackground) {
- X XFillRectangle(dpy, ItemWindow(item),
- X (high) ? MenuNormalGC(menu) : MenuInvertGC(menu),
- X 0, 0, MenuWidth(menu), item->itemHeight);
- X
- X /*
- X * Draw the check mark, possibly dimmed, wherever is necessary.
- X */
- X }
- X if(TestItemFlag(item, itemChecked)){
- X XCopyArea (dpy, MenuCheckmarkPixmap(menu),
- X ItemWindow(item),
- X theGC,
- X 0, 0, checkMarkWidth, checkMarkHeight,
- X (int) x, (item->itemHeight - checkMarkHeight) / 2);
- X }
- X /* Draw submenu indicator arrow */
- X if(ItemSubmenu(item)) {
- X XCopyArea (dpy, MenuArrowPixmap(menu),
- X ItemWindow(item),
- X theGC,
- X 0, 0,
- X arrow_width, arrow_height,
- X (int) (x + MenuItemWidth(menu) -
- X arrow_width - MenuItemPad(menu)),
- X (item->itemHeight - arrow_height) / 2 - 1);
- X }
- X /*
- X * Draw the text, centered vertically.
- X */
- X if (!item->itemBackground) {
- X if (!TestItemFlag(item, itemDeaf)) {
- X pad = (item->itemHeight -
- X (MFontInfo->ascent + MFontInfo->descent)) / 2;
- X y = item->itemHeight - pad - MFontInfo->descent;
- X
- X XDrawImageString(dpy, ItemWindow(item),
- X theGC,
- X x1, y, ItemText(item), ItemTextLength(item));
- X if (TestItemFlag(item, itemDisabled))
- X {
- X gcValues.fill_style = FillSolid;
- X XChangeGC(dpy, theGC,
- X (GCFillStyle), &gcValues);
- X }
- X
- X }
- X else {
- X pad = (item->itemHeight - (MBoldFontInfo->ascent +
- X MBoldFontInfo->descent)) / 2;
- X y = item->itemHeight - pad - MBoldFontInfo->descent;
- X XDrawImageString(dpy, ItemWindow(item), menu->boldGC, x1, y,
- X ItemText(item), ItemTextLength(item));
- X }
- X }
- X Leave_void
- X}
- X
- X
- X/*
- X * UnmapMenu() unmaps a menu, if it is currently mapped.
- X */
- Xstatic void UnmapMenu(menu)
- XMenu *menu;
- X{
- X Entry("UnmapMenu")
- X
- X if(!menu || !(TestMenuFlag(menu, menuMapped)))
- X Leave_void
- X XUnmapWindow(dpy, MenuWindow(menu));
- X
- X if (TestOptionFlag(menu, savebits))
- X {
- X if (MenuSavedPixmap(menu))
- X XCopyArea (dpy,
- X MenuSavedPixmap(menu),
- X RootWindow (dpy, scr),
- X MenuNormalGC(menu),
- X 0, 0,
- X MenuWidth(menu) + 2*MenuBorderWidth(menu),
- X MenuHeight(menu) + 2*MenuBorderWidth(menu),
- X MenuX(menu), MenuY(menu));
- X
- X }
- X ResetMenuFlag(menu, menuMapped);
- X Leave_void
- X}
- X
- X
- Xstatic Boolean SetupMenuWindow (menu)
- XMenu *menu;
- X{
- X int changed = TestMenuFlag(menu, (menuChanged | menuItemChanged));
- X
- X Entry("SetupMenuWindow")
- X
- X if (contexts_created == FALSE) {
- X contexts_created = TRUE;
- X Menu_context = XUniqueContext();
- X Item_context = XUniqueContext();
- X }
- X
- X /*
- X * If the entire menu has changed, throw away any saved pixmap and
- X * then call RecalcMenu().
- X */
- X
- X if(changed & menuChanged) {
- X if(!Recalc_Menu(menu))
- X Leave(FALSE)
- X changed &= ~menuItemChanged;
- X }
- X
- X if(!MenuWindow(menu)) {
- X static unsigned long valuemask =
- X CWOverrideRedirect | CWBorderPixel | CWBackPixel;
- X XSetWindowAttributes attributes;
- X
- X attributes.override_redirect = True;
- X attributes.border_pixel = MBorder;
- X attributes.background_pixel = MBackground;
- X if (SaveUnder) {
- X attributes.save_under = True;
- X valuemask |= CWSaveUnder;
- X }
- X
- X if((MenuWindow(menu) =
- X XCreateWindow(dpy,
- X RootWindow(dpy, scr),
- X 0, 0,
- X MenuWidth(menu), MenuHeight(menu),
- X MenuBorderWidth(menu),
- X DefaultDepth(dpy, scr),
- X InputOutput,
- X DefaultVisual(dpy, scr),
- X valuemask, &attributes)
- X ) == (Window)0)
- X Leave(FALSE)
- X else if (SetupItems(menu) == FALSE)
- X Leave(FALSE)
- X
- X XSaveContext(dpy, MenuWindow(menu), Menu_context, (char *) menu);
- X XMapSubwindows(dpy, MenuWindow(menu));
- X
- X XDefineCursor(dpy, MenuWindow(menu), MenuCursor(menu));
- X }
- X else if(changed & menuChanged) {
- X XResizeWindow(dpy, MenuWindow(menu),
- X MenuWidth(menu), MenuHeight(menu));
- X if (SetupItems(menu) == FALSE)
- X Leave(FALSE)
- X XMapSubwindows(dpy, MenuWindow(menu));
- X }
- X Leave(TRUE)
- X}
- X
- Xstatic Boolean SetupItems(menu)
- XMenu *menu;
- X{
- X int y;
- X MenuItem *item;
- X int changed = TestMenuFlag(menu, (menuChanged | menuItemChanged));
- X
- X Entry("SetupItems")
- X
- X for (item = MenuItems(menu), y = 0; item;
- X y += item->itemHeight, item = ItemNext(item)) {
- X if (!ItemWindow(item)) {
- X static unsigned long valuemask =
- X (CWOverrideRedirect | CWBorderPixel | CWBackPixel);
- X XSetWindowAttributes attributes;
- X
- X attributes.override_redirect = True;
- X attributes.border_pixel = MBorder;
- X attributes.background_pixel = MBackground;
- X
- X if((ItemWindow(item) =
- X XCreateWindow(dpy,
- X MenuWindow(menu),
- X 0, y,
- X MenuItemWidth(menu),
- X item->itemHeight - (2 * MItemBorder),
- X MItemBorder,
- X DefaultDepth(dpy, scr),
- X InputOutput,
- X DefaultVisual(dpy, scr),
- X valuemask, &attributes)
- X ) == (Window) 0)
- X Leave(FALSE)
- X if (item->itemBackground) {
- X XSetWindowBackgroundPixmap(dpy, ItemWindow(item),
- X item->itemBackground);
- X XFreePixmap(dpy, item->itemBackground);
- X }
- X ItemMenu(item) = menu;
- X XSaveContext(dpy, ItemWindow(item), Item_context,
- X (char *) item);
- X XDefineCursor(dpy, ItemWindow(item),
- X MenuCursor(menu));
- X }
- X
- X else if (changed & menuChanged) {
- X XResizeWindow(dpy, ItemWindow(item),
- X MenuItemWidth(menu),
- X item->itemHeight - (2 * MItemBorder));
- X XMoveWindow(dpy, ItemWindow(item), 0, y);
- X }
- X }
- X Leave(TRUE)
- X}
- X
- Xstatic void SetInputMask(menu, mask)
- XMenu *menu;
- Xunsigned int mask;
- X{
- X MenuItem *item;
- X
- X Entry("SetInputMask")
- X
- X XSelectInput(dpy, MenuWindow(menu),
- X (mask | MenuEventMask));
- X for(item = MenuItems(menu) ; item ; item = ItemNext(item))
- X {
- X if (TestItemFlag(item, itemDisabled) || TestItemFlag(item, itemDeaf))
- X XSelectInput(dpy, ItemWindow(item),
- X (mask | MenuIgnoreMask));
- X else if (ItemIsLeaf(item))
- X XSelectInput(dpy, ItemWindow(item),
- X (mask | NormalItemEventMask));
- X else
- X XSelectInput(dpy, ItemWindow(item),
- X (mask | SubmenuItemEventMask));
- X }
- X Leave_void
- X}
- X
- XMenuItem *MenuItemByData(menu, data)
- XMenu* menu;
- Xpointer data;
- X{
- X MenuItem *item;
- X
- X Entry("MenuItemByData")
- X
- X for (item = MenuItems(menu);
- X !ItemIsNull(item) && (ItemData(item) != data);
- X item = ItemNext(item));
- X
- X Leave(item)
- X}
- X
- XMenuItem *MenuItemByName (menu, name)
- XMenu *menu;
- Xchar *name;
- X{
- X MenuItem *item;
- X
- X Entry("MenuItemByName")
- X
- X for (item = MenuItems(menu); item; item = ItemNext(item))
- X if (strcmp (name, ItemText(item)) == 0)
- X Leave(item)
- X Leave(NULLITEM)
- X}
- X
- XMenuItem *MenuGetItem(menu, window)
- XMenu *menu;
- XWindow window;
- X{
- X MenuItem *foo = 0;
- X Window tmpwindow = window;
- X
- X Entry("MenuGetItem")
- X
- X if (!menu || !window)
- X Leave(NULLITEM)
- X if (window == menu->menuWindow)
- X if (menu->highlightedItem)
- X tmpwindow = menu->highlightedItem->itemWindow;
- X XFindContext(dpy, tmpwindow, Item_context, &foo);
- X Leave(foo)
- X}
- X
- XMenu *MenuGetMenu(menu, window)
- XMenu *menu;
- XWindow window;
- X{
- X Menu *bar = 0;
- X
- X Entry("MenuGetMenu")
- X
- X XFindContext(dpy, window, Menu_context, &bar);
- X Leave(bar)
- X}
- X
- Xint ItemGetMiddleY(item)
- XMenuItem *item;
- X{
- X Window child;
- X XWindowAttributes attributes;
- X int x, y;
- X
- X Entry("ItemGetMiddleY")
- X
- X XGetWindowAttributes(dpy, ItemWindow(item), &attributes);
- X XTranslateCoordinates(dpy,
- X MenuWindow(ItemMenu(item)),
- X RootWindow(dpy, scr),
- X attributes.x, attributes.y,
- X &x, &y, &child);
- X Leave((item->itemHeight / 2) + y)
- X}
- X
- Xvoid SetInitialItem(menu, item)
- XMenu *menu;
- XMenuItem *item;
- X{
- X extern char *realloc();
- X
- X Entry("SetInitialItem")
- X
- X if (MenuHasInitialItem(menu)) {
- X if (strlen(MenuInitialItemText(menu)) < strlen(ItemText(item)))
- X MenuInitialItemText(menu) =
- X realloc(MenuInitialItemText(menu),
- X strlen(ItemText(item)) + 1);
- X }
- X else
- X MenuInitialItemText(menu) =
- X allocate(char,(strlen(ItemText(item)) + 1));
- X strcpy(MenuInitialItemText(menu), ItemText(item));
- X Leave_void
- X}
- X
- Xvoid ClearInitialItem(menu)
- XMenu *menu;
- X{
- X Entry("ClearInitialItem")
- X
- X if (MenuHasInitialItem(menu)) {
- X free(MenuInitialItemText(menu));
- X MenuInitialItemText(menu) = (char *) NULL;
- X }
- X Leave_void
- X}
- X
- XMenuItem *GetInitialItem(menu)
- XMenu *menu;
- X{
- X MenuItem *item;
- X
- X Entry("GetInitialItem")
- X
- X if (MenuHasInitialItem(menu)) {
- X for(item = MenuItems(menu) ; item ; item = ItemNext(item)) {
- X if (ItemIsInitialItem(menu, item))
- X Leave(item)
- X }
- X }
- X Leave((MenuItem *) NULL)
- X}
- X
- X
- X/* Some utility functions */
- X
- Xvoid Retch(s, p1, p2, p3, p4)
- Xchar *s;
- Xlong p1, p2, p3, p4;
- X{
- X char buffer[1024];
- X
- X sprintf(buffer, s, p1, p2, p3, p4);
- X fprintf(stderr, "Error in %s %s\n", curr_rtn(), buffer);
- X return;
- X}
- END_OF_FILE
- if test 33843 -ne `wc -c <'menus/menu.c'`; then
- echo shar: \"'menus/menu.c'\" unpacked with wrong size!
- fi
- # end of 'menus/menu.c'
- fi
- if test -f 'menus/menu.ext.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'menus/menu.ext.h'\"
- else
- echo shar: Extracting \"'menus/menu.ext.h'\" \(1789 characters\)
- sed "s/^X//" >'menus/menu.ext.h' <<'END_OF_FILE'
- X
- X/*
- X#ifndef lint
- Xstatic char sccs_id[] = "@(#)menu.extern.h 2.1 12/16/87 Siemens Corporate Research and Support, Inc.";
- X#endif
- X*/
- X
- X
- X/*
- X RTL Menu Package Version 1.0
- X by Joe Camaratta and Mike Berman, Siemens RTL, Princeton NJ, 1987
- X
- X menu.extern.h: external function declarations for menu package
- X*/
- X
- X#include "X11/copyright.h"
- X/*
- X *
- X * Copyright 1987, 1988 by Ardent Computer Corporation, Sunnyvale, Ca.
- X *
- X * Copyright 1987 by Jordan Hubbard.
- X *
- X *
- X * All Rights Reserved
- X *
- X * Permission to use, copy, modify, and distribute this software and its
- X * documentation for any purpose and without fee is hereby granted,
- X * provided that the above copyright notice appear in all copies and that
- X * both that copyright notice and this permission notice appear in
- X * supporting documentation, and that the name of Ardent Computer
- X * Corporation or Jordan Hubbard not be used in advertising or publicity
- X * pertaining to distribution of the software without specific, written
- X * prior permission.
- X *
- X */
- X
- Xextern MenuItem *AddMenuItem();
- Xextern Boolean DisposeItem();
- Xextern void DisposeMenu();
- Xextern void InitMenu();
- Xextern Boolean SetItemText();
- Xextern Menu *NewMenu();
- Xextern Boolean SetItemCheck();
- Xextern Boolean SetItemDisable();
- Xextern MenuItem *Display_Menu();
- Xextern void Undisplay_Menu();
- Xextern void MenuInvert();
- Xextern void PlacePointer();
- Xextern void Draw_Menu();
- Xextern void Draw_Item();
- X
- Xextern MenuItem *MenuGetItem();
- Xextern MenuItem *MenuItemByName();
- Xextern MenuItem *MenuItemByData();
- Xextern Menu *MenuGetMenu();
- Xextern int ItemGetMiddleY();
- Xextern void SetInitialItem();
- Xextern void ClearInitialItem();
- Xextern MenuItem *GetInitialItem();
- X
- Xextern MenuItem *TrackMenu();
- X
- X
- X
- X
- X
- X
- X
- X
- X
- X
- END_OF_FILE
- if test 1789 -ne `wc -c <'menus/menu.ext.h'`; then
- echo shar: \"'menus/menu.ext.h'\" unpacked with wrong size!
- fi
- # end of 'menus/menu.ext.h'
- fi
- echo shar: End of archive 3 \(of 12\).
- cp /dev/null ark3isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 12 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Mike Wexler(wyse!mikew) Phone: (408)433-1000 x1330
- Moderator of comp.sources.x
-